﻿#include "FITKAbaqusAdaptorTransform.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "InpReadInformationMapper.h"
#include "FITKAbaqusGetInterfaceTool.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialOrientation.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaTransform.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKBoundaryLocation.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractLoad.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadConcentratedForce.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadPressure.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadMoment.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadBodyForce.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaLoadGravity.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAbstractBoundaryCondition.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionDisplacement.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaBoundaryConditionSymmetry.h"
#include "FITK_Interface/FITKInterfaceModel/FITKModelSet.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractLoadBC.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractModel.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintCoupling.h" 
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintTie.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintRigidBody.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConstraintManager.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKSectionAssign.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaPointMassInertia.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaEngineeringFeature.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaInertiaManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignment.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignmentManager.h"
#include <QTextStream>
#include <QList>
#include <QDebug>

//set集合每行不得超过16个，INP准则
#define SETCOUNT 16

namespace IO
{

    QString FITKAbaqusAdaptorTransform::getAdaptorClass()
    {
        return "FITKAbaqusAdaptorTransform";
    }

    void FITKAbaqusAdaptorTransform::setModelDataCaseData(Interface::FITKAbstractModel* modelData, AbaqusData::FITKDataCase* caseData, bool writeMaterialOrientation)
    {
        _modelData = modelData;
        _caseData = caseData;
        _isMaterialOrientation = writeMaterialOrientation;
    }

    bool FITKAbaqusAdaptorTransform::adaptR()
    {
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        bool readOK = false;
        if (sH == "transform")
        {
            readOK = this->readTransform();
        }
        else if (sH == "orientation")
        {
            readOK = this->readOrientation();
        }
        return readOK;
    }

    bool FITKAbaqusAdaptorTransform::adaptW()
    {
        //写出局部坐标系
        if (!_writer || !_dataObj || !_modelData)return false;
        bool ok = false;
        //写出part下的局部坐标系
        if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AMTMIX)
        {
            //写出材料指派方向
            if (_isMaterialOrientation)
                ok = this->writeMaterialOrientation();
            //写出质量点局部坐标系
            if (!_isMaterialOrientation && this->isPartJudgmentOrientationW(ok))
                ok = this->writeOrientation();
        }
        //写出Assembly下的局部坐标系
        else if (_modelData->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::Assembly)
        {
            ok = true;
            //局部坐标系数据
            Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(_dataObj);
            if (!transform)return false;
            //写出Transform
            if (!this->getElementName(_dataObj->getDataObjectID())) return false;
            if (!_setNameList.isEmpty()) ok = this->writeTransform();
            //写出Orientation
            if (this->isAssemblyJudgmentOrientationW(ok)) ok &= this->writeOrientation();
        }
        return ok;
    }

    bool FITKAbaqusAdaptorTransform::isGlobalCsys()
    {
        return _isGlobal;
    }

    bool FITKAbaqusAdaptorTransform::readTransform()
    {
        Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(_dataObj);
        if (!transform || !_reader)return false;
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //获取名称并设置
        QString name = s["nset"];
        name.remove("_T-");
        transform->setDataObjectName(name);
        //读取第一个点和第二个点
        line = _reader->readLine();
        if (line.startsWith("*"))return false;
        QStringList str = line.split(',');
        if (str.size() < 6)return false;
        double p[6] = { 0.0 };
        for (int i = 0; i < 6; ++i)
        {
            bool ok = false;
            p[i] = str.at(i).toDouble(&ok);
            if (!ok)return false;
        }
        transform->setTransform(p, p + 3);
//        transform->update();
        return true;
    }

    bool FITKAbaqusAdaptorTransform::readOrientation()
    {
        Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(_dataObj);
        if (!transform || !_reader || !_modelData)return false;
        //回退一行 处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        //关键字处理
        InpKeyLineSpliter s(line, _reader);
        QString sH = s.getHeader().toLower();
        //获取名称并设置
        QString name;
        name = "Ori_" + s["name"];
        transform->setDataObjectName(name);
        bool ok = false;
        //读取数据
        line = _reader->readLine();
        if (line.startsWith("*"))return false;
        QStringList str = line.split(',');
        if (str.size() < 6)return false;
        int n = str.size();
        if (n > 9)n = 9;
        //获取第一个点,第二个点,坐标原点
        double p[9] = { 0.0 };
        for (int i = 0; i < n; ++i)
        {
            p[i] = str.at(i).toDouble(&ok);
            if (!ok)return false;
        }
        if (fabsl(p[0] - 1.0) < 1e-16 && fabsl(p[1]) < 1e-16 && fabsl(p[2]) < 1e-16 && fabsl(p[3]) < 1e-16 && fabsl(p[4] - 1.0) < 1e-16
            && fabsl(p[5]) < 1e-16 && fabsl(p[6]) < 1e-16 && fabsl(p[7]) < 1e-16 && fabsl(p[8]) < 1e-16)
            _isGlobal = true;
        //设置第一个点,第二个点,坐标原点
        transform->setTransform(p, p + 3);
        transform->setOrigin(p[6], p[7], p[8]);
        //读取数据
        line = _reader->readLine();
        if (line.startsWith("*"))return false;
        auto mapper = _reader->getReadInpInformationMapper();
        //添加到映射表
        int csysId = transform->getDataObjectID();
        if (_isGlobal) csysId = -1;
        int modelId = _modelData->getDataObjectID();
        if (mapper)
            mapper->insertOrientationInfoData(name, csysId, modelId, line);
        //str = line.split(',');
        //if (str.size() != 2)return false;
        ////获取局部方向和旋转角
        //double local = str.at(0).toDouble(&ok);
        //if (!ok)return false;
        //double angle = str.at(1).toDouble(&ok);
        //if (!ok)return false;
        return true;
    }

    bool FITKAbaqusAdaptorTransform::writeElement()
    {
        Core::FITKAbstractNDataObject* data = dynamic_cast<Core::FITKAbstractNDataObject*>(_dataObj);
        if (!_writer || !data)return false;
        QTextStream* stream = _writer->getStream();
        //获取名称
        QString name = data->getDataObjectName();
        name = name.contains(' ') ? QString("\"_T-%1\"").arg(name) : QString("_T-%1").arg(name);
        *stream << QString("*Nset, nset=%1, internal").arg(name) << endl;
        for (QString name : _setNameList)
        {
            *stream << QString("%1,").arg(name) << endl;
        }
        return true;
    }

    bool FITKAbaqusAdaptorTransform::writeOrientation()
    {
        Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(_dataObj);
        if (!transform || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        Interface::FITKCoordinateSystem::FCSysType type = transform->getSysType();
        //获取数据
        QString oriName = transform->getDataObjectName();
        oriName = oriName.contains(' ') ? QString("\"%1\"").arg(oriName) : oriName;
        QString lineOne = QString("*Orientation, name=%1").arg(oriName);
        if (type == Interface::FITKCoordinateSystem::FCSysType::FCSCylinder)
            lineOne += ", system=CYLINDRICAL";
        else if (type == Interface::FITKCoordinateSystem::FCSysType::FCSSphere)
            lineOne += ", system=SPHERICAL";
        *stream << lineOne << endl;
        double p1[3] = { 0,0,0 };
        double p2[3] = { 0,0,0 };
        transform->getTransform(p1, p2);
        //        transform->getDirection2(p2);
        lineOne = QString("%1, %2, %3, %4, %5, %6").
            arg(_writer->double2String(p1[0], 15, 12)).arg(_writer->double2String(p1[1], 15, 12)).arg(_writer->double2String(p1[2], 15, 12))
            .arg(_writer->double2String(p2[0], 15, 12)).arg(_writer->double2String(p2[1], 15, 12)).arg(_writer->double2String(p2[2], 15, 12));
        *stream << lineOne << endl;
        *stream << "1, 0." << endl;
        return true;
    }

    bool FITKAbaqusAdaptorTransform::writeMaterialOrientation()
    {
        AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
        if (!partData || !_writer || !_dataObj)return false;
        //获取管理器
        Interface::FITKAbaMaterialOrientationManager* materialOrientationManager = partData->getMaterialOrientationManager();
        Interface::FITKCoordinateSystemManager* csysManager = partData->getCoordinateSystemManager();
        if (!materialOrientationManager || !csysManager || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        //材料方向数据
        Interface::FITKAbaMaterialOrientation* orientation = dynamic_cast<Interface::FITKAbaMaterialOrientation*>(_dataObj);
        if (!orientation)return false;
        //名称
        QString name = orientation->getDataObjectName();
        name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
        int csysId = orientation->getCsysID();
        //写出坐标系类型和坐标系参数
        if (csysId == -1)
        {
            //写出全局坐标系
            QString lineOne = QString("*Orientation, name=%1").arg(name);
            *stream << lineOne << endl;
            //写出方向轴
            *stream << "1., 0., 0., 0., 1., 0." << endl;
        }
        else
        {
            Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(csysManager->getDataByID(csysId));
            if (!transform)return false;
            //写出坐标系类型
            Interface::FITKCoordinateSystem::FCSysType type = transform->getSysType();
            QString lineOne = QString("*Orientation, name=%1").arg(name);
            if (type == Interface::FITKCoordinateSystem::FCSysType::FCSCylinder)
                lineOne += ", system=CYLINDRICAL";
            else if (type == Interface::FITKCoordinateSystem::FCSysType::FCSSphere)
                lineOne += ", system=SPHERICAL";
            *stream << lineOne << endl;
            //写出方向轴
            double p1[3] = { 0,0,0 };
            double p2[3] = { 0,0,0 };
            transform->getTransform(p1, p2);
            lineOne = QString("%1, %2, %3, %4, %5, %6").
                arg(_writer->double2String(p1[0], 15, 12)).arg(_writer->double2String(p1[1], 15, 12)).arg(_writer->double2String(p1[2], 15, 12))
                .arg(_writer->double2String(p2[0], 15, 12)).arg(_writer->double2String(p2[1], 15, 12)).arg(_writer->double2String(p2[2], 15, 12));
            *stream << lineOne << endl;
        }
        //局部方向
        int local = orientation->getRotateAxis();
        //旋转角
        double angle = orientation->getRotateAngle();
        *stream << QString("%1, %2").arg(local).arg(_writer->double2String(angle, 9, 0)) << endl;
        return true;
    }

    bool FITKAbaqusAdaptorTransform::isWriteMaterialOrientation()
    {
        AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
        if (!partData || !_writer || !_dataObj)return false;
        //材料方向数据
        Interface::FITKAbaMaterialOrientation* orientation = dynamic_cast<Interface::FITKAbaMaterialOrientation*>(_dataObj);
        if (!partData || !orientation)return false;
        //获取截面指派管理器
        auto sectionAssignManager = partData->getSectionAssignManager();
        if (!sectionAssignManager)return false;
        int count = sectionAssignManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            auto assign = sectionAssignManager->getDataByIndex(i);
            if (!assign)continue;
            if (assign->getModelID() == orientation->getModelSetID())
                return true;
        }
        return false;
    }

    bool FITKAbaqusAdaptorTransform::isAssemblyJudgmentOrientationW(bool &ok)
    {
        Interface::FITKAbaAssembly* assemblyData = dynamic_cast<Interface::FITKAbaAssembly*>(_modelData);
        if (!assemblyData || !_writer || !_dataObj || !_caseData)return false;
        if (!_dataObj)return false;
        //获取约束管理器
        auto constraintManager = _caseData->getConstraintManager();
        if (!constraintManager)return false;
        //通过约束的局部坐标来判定是否写出
        int count = constraintManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractConstraint* constraint = dynamic_cast<Interface::FITKAbaAbstractConstraint*>(constraintManager->getDataByIndex(i));
            if (constraint->getConstraintType() == Interface::FITKAbaAbstractConstraint::FITKAbaConstraintType::Coupling)
            {
                //坐标系一致即可写出
                Interface::FITKAbaConstraintCoupling* couping = dynamic_cast<Interface::FITKAbaConstraintCoupling*>(constraint);
                if (couping && couping->getCsysId() == _dataObj->getDataObjectID())
                    return true;
            }
        }
        //获取装配下的工程特性
        Interface::FITKAbaAssemblyEngineeringFeature* engineeringFeatureAssembly = assemblyData->getAssemblyEngineerFeature();
        if (!engineeringFeatureAssembly)return false;
        //获取惯量管理器
        Interface::FITKAbaInertiaManager* inertiaManager = engineeringFeatureAssembly->getInertiaManager();
        if (!inertiaManager)return false;
        //通过惯量的局部坐标来判定是否写出
        count = inertiaManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractInertia* inertia = inertiaManager->getDataByIndex(i);
            if (!inertia)continue;
            //获取质量点类型
            Interface::FITKAbaAbstractInertia::FITKAbaInertiaType type = inertia->getInertiaType();
            if (type != Interface::FITKAbaAbstractInertia::FITKAbaInertiaType::PointMassInertia)continue;
            //获取点质量/惯量是否存在当前局部坐标系
            Interface::FITKAbaInertiaPointMassInertia* pointMassInertia = dynamic_cast<Interface::FITKAbaInertiaPointMassInertia*>(inertia);
            if (pointMassInertia && pointMassInertia->getCsysId() == _dataObj->getDataObjectID())
                return true;
        }
        //获取连接器指派管理
        Interface::FITKAbaConnectorAssignmentManager* assignConnectManager = assemblyData->getConnectorAssignManager();
        if (!assignConnectManager)return false;
        //通过连接器指派的局部坐标来判定是否写出
        count = assignConnectManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaConnectorAssignment* assignData = assignConnectManager->getDataByIndex(i);
            if (!assignData)continue;
            //坐标系1和坐标系2
            if (_dataObj->getDataObjectID() == assignData->getCsysId1())
                return true;
            if (_dataObj->getDataObjectID() == assignData->getCsysId2())
                return true;
        }
        ok = true;
        return false;
    }

    bool FITKAbaqusAdaptorTransform::isPartJudgmentOrientationW(bool &ok)
    {
        AbaqusData::FITKAbaqusPart* partData = dynamic_cast<AbaqusData::FITKAbaqusPart*>(_modelData);
        if (!partData || !_writer || !_dataObj)return false;
        //获取装配下的工程特性
        Interface::FITKAbaPartEngineeringFeature* engineeringFeatureAssembly = partData->getPartEngineerFeature();
        if (!engineeringFeatureAssembly)return false;
        //获取惯量管理器
        Interface::FITKAbaInertiaManager* inertiaManager = engineeringFeatureAssembly->getInertiaManager();
        if (!inertiaManager)return false;
        //通过惯量的局部坐标来判定是否写出
        int count = inertiaManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractInertia* inertia = inertiaManager->getDataByIndex(i);
            if (!inertia)continue;
            //获取质量点类型
            Interface::FITKAbaAbstractInertia::FITKAbaInertiaType type = inertia->getInertiaType();
            if (type != Interface::FITKAbaAbstractInertia::FITKAbaInertiaType::PointMassInertia)continue;
            //获取点质量/惯量是否存在当前局部坐标系
            Interface::FITKAbaInertiaPointMassInertia* pointMassInertia = dynamic_cast<Interface::FITKAbaInertiaPointMassInertia*>(inertia);
            if (pointMassInertia && pointMassInertia->getCsysId() == _dataObj->getDataObjectID())
                return true;
        }
        ok = true;
        return false;
    }

    bool FITKAbaqusAdaptorTransform::writeTransform()
    {
        if (!this->writeElement())
            return false;
        Interface::FITKAbaTransform* transform = dynamic_cast<Interface::FITKAbaTransform*>(_dataObj);
        if (!transform || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        Interface::FITKCoordinateSystem::FCSysType type = transform->getSysType();
        QString transName = transform->getDataObjectName();
        transName = transName.contains(' ') ? QString("\"_T-%1\"").arg(transName) : QString("_T-%1").arg(transName);
        QString lineOne = QString("*Transform, nset=%1").arg(transName);
        if (type == Interface::FITKCoordinateSystem::FCSysType::FCSCylinder)
            lineOne += ", type=C";
        else if (type == Interface::FITKCoordinateSystem::FCSysType::FCSSphere)
            lineOne += ", type=S";
        *stream << lineOne << endl;
        double p1[3] = { 0,0,0 };
        double p2[3] = { 0,0,0 };
        transform->getTransform(p1,p2);
//        transform->getDirection2(p2);
        lineOne = QString("%1, %2, %3, %4, %5, %6").
            arg(_writer->double2String(p1[0], 15, 12)).arg(_writer->double2String(p1[1], 15, 12)).arg(_writer->double2String(p1[2], 15, 12))
           .arg(_writer->double2String(p2[0], 15, 12)).arg(_writer->double2String(p2[1], 15, 12)).arg(_writer->double2String(p2[2], 15, 12));
        *stream << lineOne << endl;
        return true;
    }

    bool FITKAbaqusAdaptorTransform::getElementName(int transformId)
    {
        if (!_caseData)return false;
        auto bcManager = _caseData->getBCManager();
        auto loadManager = _caseData->getLoadManager();
        if (!bcManager || !loadManager)return false;
        int count = loadManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractLoad* load = dynamic_cast<Interface::FITKAbaAbstractLoad*>(loadManager->getDataByIndex(i));
            if (!load)continue;
            Interface::FITKAbaAbstractLoad::FITKAbaLoadType type = load->getLoadType();
            int tranId = 0;
            if (type == Interface::FITKAbaAbstractLoad::FITKAbaLoadType::ConcentratedForce)
            {
                Interface::FITKAbaLoadConcentratedForce* cLoad = dynamic_cast<Interface::FITKAbaLoadConcentratedForce*>(load);
                if (!cLoad)continue;
                tranId = cLoad->getCsysId();
            }
            else if (type == Interface::FITKAbaAbstractLoad::FITKAbaLoadType::Moment)
            {
                Interface::FITKAbaLoadMoment* cLoad = dynamic_cast<Interface::FITKAbaLoadMoment*>(load);
                if (!cLoad)continue;
                tranId = cLoad->getCsysId();
            }
            if (transformId == tranId)
            {
                auto set = load->getComponentObj();
                if (!set)return false;
                QString setName = set->getDataObjectName();
                setName = setName.contains(' ') ? QString("\"%1\"").arg(setName) : setName;
                //用于判断set是否在part下
                if (load->getModelID() != set->getAbsModelID() && load->getModelID() > 0)
                {
                    QString name = load->getModelObj()->getDataObjectName();
                    name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                    setName = name + "." + setName;
                }
                if (!_setNameList.contains(setName))
                    _setNameList.append(setName);
            }
        }
        count = bcManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            Interface::FITKAbaAbstractBoundaryCondition* boundary = dynamic_cast<Interface::FITKAbaAbstractBoundaryCondition*>(bcManager->getDataByIndex(i));
            if (!boundary)continue;
            Interface::FITKAbaAbstractBoundaryCondition::FITKAbaBoundaryConditionType type = boundary->getBoundaryConditionType();
            int tranId = 0;
            if (type == Interface::FITKAbaAbstractBoundaryCondition::FITKAbaBoundaryConditionType::SymmetryAntisymmetryEncastre)
            {
                Interface::FITKAbaBoundaryConditionSymmetry* data = dynamic_cast<Interface::FITKAbaBoundaryConditionSymmetry*>(boundary);
                if (!data)continue;
                tranId = data->getCsysId();
            }
            else if (type == Interface::FITKAbaAbstractBoundaryCondition::FITKAbaBoundaryConditionType::DisplacementRotation)
            {
                Interface::FITKAbaBoundaryConditionDisplacement* data = dynamic_cast<Interface::FITKAbaBoundaryConditionDisplacement*>(boundary);
                if (!data)continue;
                tranId = data->getCsysId();
            }
            if (transformId == tranId)
            {
                auto set = boundary->getComponentObj();
                if (!set)return false;
                QString setName = set->getDataObjectName();
                setName = setName.contains(' ') ? QString("\"%1\"").arg(setName) : setName;
                //用于判断set是否在part下
                if (boundary->getModelID() != set->getAbsModelID() && boundary->getModelID() > 0)
                {
                    QString name = boundary->getModelObj()->getDataObjectName();
                    name = name.contains(' ') ? QString("\"%1\"").arg(name) : name;
                    setName = name + "." + setName;
                }
                if (!_setNameList.contains(setName))
                    _setNameList.append(setName);
            }
        }
        return true;
    }
}
